package access

import (
	"errors"
	"net/http"

	"server/common"

	"github.com/gin-gonic/gin"
	"github.com/google/uuid"
	"github.com/gorilla/websocket"
	"github.com/sirupsen/logrus"
)

type AccessService struct {
	dispatcher  common.IMsgDispatcher
	upgrader    websocket.Upgrader
	connMgr     *ConnManager
	router      *gin.Engine
	serviceInfo common.ServiceInfo
}

// -------------------------------------------------------------------------------------------------
//
// -------------------------------------------------------------------------------------------------
func NewAccessService(dispatcher common.IMsgDispatcher) *AccessService {
	if dispatcher == nil {
		panic("dispatcher cannot be nil")
	}
	return &AccessService{
		dispatcher: dispatcher,
		upgrader: websocket.Upgrader{
			CheckOrigin: func(r *http.Request) bool {
				return true // 允许所有跨域请求
			},
		},
		router:  gin.Default(),
		connMgr: NewConnManager(),
	}
}

// -------------------------------------------------------------------------------------------------
//
// -------------------------------------------------------------------------------------------------
func (s *AccessService) Init() error {
	s.serviceInfo = common.ServiceInfo{
		ServiceType: common.SERVICE_TYPE_ACCESS,
		ServiceId:   uuid.New().String(),
	}

	if err := s.dispatcher.Register(s.serviceInfo, s); err != nil {
		common.Logger(common.SERVICE_TYPE_ACCESS).WithError(err).
			Error("Failed to register AccessService with dispatcher")
		return err
	}

	s.router.GET("/", s.HandleWebSocket)

	return nil
}

// -------------------------------------------------------------------------------------------------
//
// -------------------------------------------------------------------------------------------------
func (s *AccessService) Start(serverAddr string) error {
	common.Logger(common.SERVICE_TYPE_ACCESS).Infof("starting access service at %s", serverAddr)
	return http.ListenAndServe(serverAddr, s.router)
}

// -------------------------------------------------------------------------------------------------
//
// -------------------------------------------------------------------------------------------------
func (s *AccessService) Stop() error {
	common.Logger(common.SERVICE_TYPE_ACCESS).Info("stopping access service")
	// 这里可以添加清理资源的逻辑
	return nil
}

// -------------------------------------------------------------------------------------------------
//
// -------------------------------------------------------------------------------------------------
func (s *AccessService) HandleMsg(msg common.Message, from common.ServiceInfo, connId string) error {
	common.Logger(common.SERVICE_TYPE_ACCESS, msg.Rid).WithFields(logrus.Fields{
		"msg":    common.ToJson(msg),
		"from":   from,
		"connId": connId,
	}).Debug("received message in access service")

	// Connection ID (connId) is required for unicast messages
	if connId == "" {
		return errors.New("connection ID (connId) is empty")
	}

	return s.sendMsgToConnection(msg, connId)
}
